package cn.xny.txcc.service.impl;

import cn.xny.txcc.domain.CourseType;
import cn.xny.txcc.dto.CourseTypeCrumbsVo;
import cn.xny.txcc.mapper.CourseTypeMapper;
import cn.xny.txcc.service.ICourseTypeService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author whale
 * @since 2023-03-11
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    public List<CourseType> treeData() {
        /**
         * 先从redis中获取数据有则返回没有则查询数据库并且保存到redis中
         */
        List<CourseType>  treeData = (List<CourseType>) redisTemplate.opsForValue().get("treeData");
         if (treeData == null)  {treeDateInDB();}
        return treeDateInDB();
    }



    private List<CourseType> treeDateInDB() {

        List<CourseType> treeData = new ArrayList<>(); // 防止空指针
        // 查询出所有的类型
        List<CourseType> courseTypes = super.selectList(null);

        Map<Long, CourseType> map = courseTypes.stream().collect(Collectors.toMap(CourseType::getId, courseType -> courseType));
        // 将查询出来的所有的装在一个map里面
//        Map<Long, CourseType> map = new HashMap<>();
//        for (CourseType courseType : courseTypes){
//            map.put(courseType.getId(), courseType);
//        }
        // 准备一个空集合用于返回treeDate

        // 遍历数据进行组装
        // 如果没有父id就是顶级分类 放回到返回数据中
        for (CourseType courseType : courseTypes) {
            if (courseType.getPid() == 0 || courseType.getPid() == null) {
                treeData.add(courseType);
            } else {
                // 如果不是顶级分类找到自己的顶级分类再将自己放到父级分类中
                map.get(courseType.getPid()).getChildren().add(courseType);
            }
        }
        // 设置到redis中
        redisTemplate.opsForValue().set("treeData", treeData);
        return treeData;
    }

    /**
     * 数据库做了增删操作 需要同步到redis中 数据库数据改变redis也要改变
     * 1 重写增删改方法 删除redis中的数据
     * 2 先更新数据库，然后再删除缓存
     * 3.延时双删策略 先删缓存 再写数据库 在删缓存
     * @param entity
     * @return
     */
    @Override
    public boolean insert(CourseType entity) {
        boolean bool = super.insert(entity);
        if (bool) redisTemplate.delete("treeData");
        return bool;
    }
    @CacheEvict(cacheNames = "treeData",key = "'ALL'")
    @Override
    public boolean deleteById(Serializable id) {
        return super.deleteById(id);
    }

    @Override
    public boolean updateById(CourseType entity) {
        boolean b = super.updateById(entity);
        if (b) redisTemplate.delete("treeData");
        return b;

    }


    @Override
    public List getCourseType(Long courseTypeId) {


        CourseType courseType = super.selectById(courseTypeId);
        List<CourseTypeCrumbsVo> courseTypes = new ArrayList<>();

        String[] split = courseType.getPath().split("\\.");
        if(split.length==1){
            CourseTypeCrumbsVo courseTypeCrumbsVo = new CourseTypeCrumbsVo();
                courseTypeCrumbsVo.setOwnerProductType(courseType);
                 Long pid = courseType.getPid();
            Wrapper<CourseType> wrapper = new EntityWrapper<>();
                 wrapper.eq("pid",pid);
            List<CourseType> courseTypes1 = super.selectList(wrapper);
            courseTypeCrumbsVo.setOtherProductTypes(courseTypes1);
            courseTypes.add(courseTypeCrumbsVo);

        }else {

            for (int i=0;i<split.length;i++) {
                CourseTypeCrumbsVo courseTypeCrumbsVo = new CourseTypeCrumbsVo();
                CourseType courseType1 = super.selectById(split[i]);
                courseTypeCrumbsVo.setOwnerProductType(courseType1);
                Long pid = courseType1.getPid();
                Wrapper<CourseType> wrapper = new EntityWrapper<>();
                wrapper.eq("pid",pid);
                List<CourseType> courseTypes2 = super.selectList(wrapper);
                courseTypeCrumbsVo.setOtherProductTypes(courseTypes2);

                courseTypes.add(courseTypeCrumbsVo);
            }
        }

        return courseTypes;
    }


    }



